#include "preHeader.h"
#include "Session/GameSession.h"
#include "Session/GameSessionHandler.h"
#include "SQLHelper.h"

int GameSessionHandler::HandleLoadAllGuildInfo(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllGuildInfo = [GSRPCAsyncTaskArgs]() {
		TNetBuffer<65536> buffer;
		size_t n = 0;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			uint32 lastInstID = 0;
			auto sqlFormat = CreateSQL4SelectEntity<GuildInformation>("Id>%u ORDER BY Id");
mark:		auto rst = connPtr->FastQueryFormat(sqlFormat.c_str(), lastInstID);
			if (rst) {
				while (rst.NextRow()) {
					auto row = rst.Fetch();
					auto instInfo = LoadEntityFromMysqlRow<GuildInformation>(row);
					SaveToINetStream(instInfo, buffer);
					lastInstID = instInfo.Id;
					if (++n % 250 == 0) {
						GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
						buffer.Clear();
					}
				}
				if (connPtr->GetLastErrno() == 0) {
					GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, true);
				} else {
					goto mark;
				}
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorQueryMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllGuildInfo));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleLoadAllGuildMember(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllGuildMember = [GSRPCAsyncTaskArgs]() {
		TNetBuffer<65536> buffer;
		size_t n = 0;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			uint32 lastInstID = 0;
			auto sqlFormat = CreateSQL4SelectEntity<GuildMember>("playerId>%u ORDER BY playerId");
mark:		auto rst = connPtr->FastQueryFormat(sqlFormat.c_str(), lastInstID);
			if (rst) {
				while (rst.NextRow()) {
					auto row = rst.Fetch();
					auto instInfo = LoadEntityFromMysqlRow<GuildMember>(row);
					SaveToINetStream(instInfo, buffer);
					lastInstID = instInfo.playerId;
					if (++n % 2500 == 0) {
						GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
						buffer.Clear();
					}
				}
				if (connPtr->GetLastErrno() == 0) {
					GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, true);
				} else {
					goto mark;
				}
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorQueryMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllGuildMember));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleLoadAllGuildApply(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllGuildApply = [GSRPCAsyncTaskArgs]() {
		TNetBuffer<65536> buffer;
		size_t n = 0;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			uint32 lastInstID[2]{};
			auto sqlFormat = CreateSQL4SelectEntity<GuildApply>(
				"playerId>%u OR (playerId=%u AND guildId>%u) ORDER BY playerId,guildId");
mark:		auto rst = connPtr->FastQueryFormat(
				sqlFormat.c_str(), lastInstID[0], lastInstID[0], lastInstID[1]);
			if (rst) {
				while (rst.NextRow()) {
					auto row = rst.Fetch();
					auto instInfo = LoadEntityFromMysqlRow<GuildApply>(row);
					SaveToINetStream(instInfo, buffer);
					lastInstID[0] = instInfo.playerId;
					lastInstID[1] = instInfo.guildId;
					if (++n % 2500 == 0) {
						GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
						buffer.Clear();
					}
				}
				if (connPtr->GetLastErrno() == 0) {
					GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, true);
				} else {
					goto mark;
				}
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorQueryMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllGuildApply));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewOneGuildInstance(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewOneGuildInstance = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		GuildInformation instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4InsertEntity(instInfo);
			auto rst = connPtr->Execute(sqlStr.c_str());
			if (rst.second) {
				buffer << (u32)connPtr->GetInsertID();
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewOneGuildInstance));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleSaveOneGuildInstance(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto SaveOneGuildInstance = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		GuildInformation instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4UpdateEntity(instInfo, "Id=%u");
			auto rst = connPtr->ExecuteFormat(sqlStr.c_str(), instInfo.Id);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(SaveOneGuildInstance));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteOneGuildInstance(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteOneGuildInstance = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		auto Id = pckPtr->Read<uint32>();
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4DeleteEntity<GuildInformation>("Id=%u");
			auto rst = connPtr->ExecuteFormat(sqlStr.c_str(), Id);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteOneGuildInstance));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewOneGuildMember(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewOneGuildMember = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		GuildMember instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4InsertEntity(instInfo);
			auto rst = connPtr->Execute(sqlStr.c_str());
			if (rst.second) {
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewOneGuildMember));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleSaveOneGuildMember(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto SaveOneGuildMember = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		GuildMember instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4UpdateEntity(instInfo, "playerId=%u");
			auto rst = connPtr->ExecuteFormat(sqlStr.c_str(), instInfo.playerId);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(SaveOneGuildMember));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteOneGuildMember(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteOneGuildMember = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		auto playerId = pckPtr->Read<uint32>();
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4DeleteEntity<GuildMember>("playerId=%u");
			auto rst = connPtr->ExecuteFormat(sqlStr.c_str(), playerId);
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteOneGuildMember));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewOneGuildApply(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewOneGuildApply = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		GuildApply instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			auto sqlStr = CreateSQL4InsertEntity(instInfo);
			auto rst = connPtr->Execute(sqlStr.c_str());
			if (rst.second) {
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorInsertMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewOneGuildApply));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteGuildApply(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteGuildApply = [GSRPCAsyncTaskArgs]() {
		NetBuffer buffer;
		uint32 playerId, guildId;
		(*pckPtr) >> playerId >> guildId;
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (connPtr) {
			std::pair<my_ulonglong, bool> rst;
			if (playerId != 0 && guildId != 0) {
				rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<GuildApply>
					("playerId=%u AND guildId=%u").c_str(), playerId, guildId);
			} else if (playerId != 0) {
				rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<GuildApply>
					("playerId=%u").c_str(), playerId);
			} else {
				rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<GuildApply>
					("guildId=%u").c_str(), guildId);
			}
			if (rst.second) {
				buffer << (u32)rst.first;
				GameSession::Feedback(gsPtr, buffer, info.sn);
			} else {
				GameSession::FeedbackError(gsPtr, info.sn, DBPErrorUpdateMysqlFailed);
			}
		} else {
			GameSession::FeedbackError(gsPtr, info.sn, DBPErrorConnectMysqlFailed);
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteGuildApply));
	return SessionHandleCapture;
}
